package com.autumn.mybatis.context;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.support.ManagedArray;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.util.StringUtils;

import com.autumn.mybatis.BeanConstant;
import com.autumn.mybatis.annotation.EnableAutumnMybatis;
import com.autumn.mybatis.annotation.EnableAutumnMybatisDynamicDataSource;
import com.autumn.mybatis.annotation.EnableAutumnMybatisMultipleDataSource;
import com.autumn.mybatis.factory.DynamicNameRoutingDataSource;
import com.autumn.mybatis.factory.DynamicSingleRoutingDataSource;
import com.autumn.mybatis.mapper.MapperRegister;
import com.autumn.mybatis.provider.IDbProvider;
import com.autumn.mybatis.provider.ProviderUtils;
import com.autumn.spring.boot.bean.BeanDefinitionRegisterManager;
import com.autumn.util.ExceptionUtils;
import com.autumn.util.TypeUtils;
import com.autumn.util.tuple.TupleTwo;

/**
 * Mapper 扫描注册帮助
 * 
 * @author 老码农
 *         <p>
 *         Description
 *         </p>
 * @date 2017-12-03 12:27:55
 */
class DefinitionRegistrarUtils {

	private static final String CLASSPATH_REPLACE = "classpath:";

	private static final String MYBATIS_PAHT_DEFAULT = "mybatis";

	/**
	 * 注册单数据源
	 * 
	 * @param definitionRegistrar
	 *            注册定义
	 * @param info
	 *            信息
	 * @param provider
	 *            驱动
	 */
	public static void registerSingleDataSource(BeanDefinitionRegisterManager definitionRegistrar,
			DefinitionRegistrarInfo info, TupleTwo<String, Class<? extends IDbProvider>> provider) {
		RuntimeBeanReference ref;
		if (!com.autumn.util.StringUtils.isNullOrBlank(info.getDataSourceFactoryBeanName())) {
			// 数据源工厂
			ref = new RuntimeBeanReference(info.getDataSourceFactoryBeanName());
		} else {
			if (info.getDataSourceFactoryType() == null) {
				throw ExceptionUtils.throwConfigureException("未配置 dataSourceFactoryType 属性。");
			}
			if (TypeUtils.isAbstract(info.getDataSourceFactoryType())) {
				throw ExceptionUtils.throwConfigureException(" dataSourceFactoryType 属性不能为抽象类型。");
			}
			String beanName = BeanConstant.getDataSourceFactoryBeanName(info.getName());
			// 注册数据源工厂
			GenericBeanDefinition dataSourceFactoryBean = definitionRegistrar
					.createBeanDefinition(info.getDataSourceFactoryType(), null, null, null);
			dataSourceFactoryBean.setPrimary(info.isPrimary());
			if (!definitionRegistrar.registerBean(beanName, dataSourceFactoryBean)) {
				throw ExceptionUtils.throwConfigureException("已存在 dataSourceFactory Bean :" + beanName);
			}
			ref = new RuntimeBeanReference(beanName);
		}
		// 注册数据源
		GenericBeanDefinition dataSourceBean = definitionRegistrar
				.createBeanDefinition(DynamicSingleRoutingDataSource.class, null, null, "close");
		dataSourceBean.setPrimary(info.isPrimary());
		dataSourceBean.getConstructorArgumentValues().addGenericArgumentValue(ref);
		dataSourceBean.getConstructorArgumentValues()
				.addGenericArgumentValue(new RuntimeBeanReference(provider.getItem1()));
		if (!definitionRegistrar.registerBean(info.getDataSourceBeanName(), dataSourceBean)) {
			throw ExceptionUtils.throwConfigureException("已存在 DataSource Bean :" + info.getDataSourceBeanName());
		}
		registerSession(definitionRegistrar, info);
	}

	/**
	 * 注册动态数据源
	 * 
	 * @param definitionRegistrar
	 *            注册定义
	 * @param info
	 *            信息
	 * @param provider
	 *            驱动类型
	 */
	public static void registerDynamicDataSource(BeanDefinitionRegisterManager definitionRegistrar,
			DefinitionRegistrarInfo info, TupleTwo<String, Class<? extends IDbProvider>> provider) {
		RuntimeBeanReference ref;
		if (!com.autumn.util.StringUtils.isNullOrBlank(info.getDataSourceFactoryBeanName())) {
			// 数据源工厂
			ref = new RuntimeBeanReference(info.getDataSourceFactoryBeanName());
		} else {
			if (info.getDataSourceFactoryType() == null) {
				throw ExceptionUtils.throwConfigureException("未配置 dataSourceFactoryType 属性。");
			}
			if (TypeUtils.isAbstract(info.getDataSourceFactoryType())) {
				throw ExceptionUtils.throwConfigureException(" dataSourceFactoryType 属性不能为抽象类型。");
			}
			String beanName = BeanConstant.getDataSourceFactoryBeanName(info.getName());
			// 注册数据源工厂
			GenericBeanDefinition dataSourceFactoryBean = definitionRegistrar
					.createBeanDefinition(info.getDataSourceFactoryType(), null, null, null);
			dataSourceFactoryBean.setPrimary(info.isPrimary());
			if (!definitionRegistrar.registerBean(beanName, dataSourceFactoryBean)) {
				throw ExceptionUtils.throwConfigureException("已存在 dataSourceFactory Bean :" + beanName);
			}
			ref = new RuntimeBeanReference(beanName);
		}
		if (info.getDataSourceRoutingType() == null) {
			throw ExceptionUtils.throwConfigureException("未配置 " + ATTRIBUTE_DATA_SOURCE_ROUTING_TYPE + " 属性。");
		}
		if (TypeUtils.isAbstract(info.getDataSourceRoutingType())) {
			throw ExceptionUtils.throwConfigureException(ATTRIBUTE_DATA_SOURCE_ROUTING_TYPE + " 属性不能为抽象类型。");
		}
		// 注册数据源
		GenericBeanDefinition dataSourceBean = definitionRegistrar.createBeanDefinition(info.getDataSourceRoutingType(),
				null, null, "close");
		dataSourceBean.setPrimary(info.isPrimary());
		dataSourceBean.getConstructorArgumentValues().addGenericArgumentValue(ref);
		dataSourceBean.getConstructorArgumentValues()
				.addGenericArgumentValue(new RuntimeBeanReference(provider.getItem1()));
		if (!definitionRegistrar.registerBean(info.getDataSourceBeanName(), dataSourceBean)) {
			throw ExceptionUtils.throwConfigureException("已存在 DataSource Bean :" + info.getDataSourceBeanName());
		}
		registerSession(definitionRegistrar, info);
	}

	/**
	 * 注册动态数据源
	 * 
	 * @param definitionRegistrar
	 *            注册定义
	 * @param infos
	 *            信息集合
	 */
	public static void registerMultipleDataSource(BeanDefinitionRegisterManager definitionRegistrar,
			List<MultipleDefinitionRegistrarInfo> infos) {
		if (infos.size() == 0) {
			return;
		}
		DefinitionRegistrarInfo mainInfo = infos.get(0).getInfo();
		RuntimeBeanReference ref;
		if (!com.autumn.util.StringUtils.isNullOrBlank(mainInfo.getDataSourceFactoryBeanName())) {
			// 数据源工厂
			ref = new RuntimeBeanReference(mainInfo.getDataSourceFactoryBeanName());
		} else {
			if (mainInfo.getDataSourceFactoryType() == null) {
				throw ExceptionUtils.throwConfigureException("未配置 dataSourceFactoryType 属性。");
			}
			if (TypeUtils.isAbstract(mainInfo.getDataSourceFactoryType())) {
				throw ExceptionUtils.throwConfigureException(" dataSourceFactoryType 属性不能为抽象类型。");
			}
			String beanName = BeanConstant.getDataSourceFactoryBeanName("multiple");
			// 注册数据源工厂
			GenericBeanDefinition dataSourceFactoryBean = definitionRegistrar
					.createBeanDefinition(mainInfo.getDataSourceFactoryType(), null, null, null);
			dataSourceFactoryBean.setPrimary(true);
			if (!definitionRegistrar.registerBean(beanName, dataSourceFactoryBean)) {
				throw ExceptionUtils.throwConfigureException("已存在 dataSourceFactory Bean :" + beanName);
			}
			ref = new RuntimeBeanReference(beanName);
		}
		for (MultipleDefinitionRegistrarInfo info : infos) {
			// 注册数据源
			GenericBeanDefinition dataSourceBean = definitionRegistrar
					.createBeanDefinition(DynamicNameRoutingDataSource.class, null, null, "close");
			dataSourceBean.setPrimary(info.getInfo().isPrimary());
			dataSourceBean.getConstructorArgumentValues().addGenericArgumentValue(ref);
			dataSourceBean.getConstructorArgumentValues()
					.addGenericArgumentValue(new RuntimeBeanReference(info.getProviderInfo().getItem1()));
			dataSourceBean.getConstructorArgumentValues().addGenericArgumentValue(info.getInfo().getName());
			if (!definitionRegistrar.registerBean(info.getInfo().getDataSourceBeanName(), dataSourceBean)) {
				throw ExceptionUtils
						.throwConfigureException("已存在 DataSource Bean :" + info.getInfo().getDataSourceBeanName());
			}
			registerSession(definitionRegistrar, info.getInfo());
		}
	}

	/**
	 * 注册会话
	 * 
	 * @param definitionRegistrar
	 * @param info
	 */
	private static void registerSession(BeanDefinitionRegisterManager definitionRegistrar,
			DefinitionRegistrarInfo info) {
		RuntimeBeanReference ref;

		// 注册事务
		ref = new RuntimeBeanReference(info.getDataSourceBeanName());
		GenericBeanDefinition transactionManagerBeanDef = definitionRegistrar
				.createBeanDefinition(DataSourceTransactionManager.class, null, null, null);
		transactionManagerBeanDef.setPrimary(info.isPrimary());
		transactionManagerBeanDef.getConstructorArgumentValues().addGenericArgumentValue(ref);
		definitionRegistrar.registerBean(info.getTransactionManagerBeanName(), transactionManagerBeanDef);

		// 注册会话工厂
		ref = new RuntimeBeanReference(info.getDataSourceBeanName());
		GenericBeanDefinition sqlSessionFactoryBeanDef = definitionRegistrar
				.createBeanDefinition(SqlSessionFactoryBean.class, null, null, null);
		sqlSessionFactoryBeanDef.setPrimary(info.isPrimary());
		sqlSessionFactoryBeanDef.getPropertyValues().add("dataSource", ref);
		if (info.getTypeAliasesPackage() != null && !"".equals(info.getTypeAliasesPackage().trim())) {
			sqlSessionFactoryBeanDef.getPropertyValues().add("typeAliasesPackage", info.getTypeAliasesPackage());
		}
		if (info.getMapperLocations() != null) {
			sqlSessionFactoryBeanDef.getPropertyValues().add("mapperLocations", info.getMapperLocations());
		}
		if (info.getConfigLocation() != null) {
			sqlSessionFactoryBeanDef.getPropertyValues().add("configLocation", info.getConfigLocation());
		}
		if (info.getPluginTypes() != null && info.getPluginTypes().length > 0) {
			ManagedArray pluginTypeRefs = new ManagedArray(Interceptor.class.getName(), info.getPluginTypes().length);
			for (Class<?> pluginType : info.getPluginTypes()) {
				GenericBeanDefinition pluginTypeBeanDef = definitionRegistrar.createBeanDefinition(pluginType, null,
						null, null);
				pluginTypeBeanDef.setPrimary(info.isPrimary());
				String pluginBeanName;
				if (com.autumn.util.StringUtils.isNullOrBlank(info.getName())) {
					pluginBeanName = definitionRegistrar.generateBeanName(pluginType);
				} else {
					pluginBeanName = info.getName() + com.autumn.util.StringUtils
							.upperCaseCapitalize(definitionRegistrar.generateBeanName(pluginType));
				}
				if (definitionRegistrar.registerBean(pluginBeanName, pluginTypeBeanDef)) {
					pluginTypeRefs.add(new RuntimeBeanReference(pluginBeanName));
					// definitionRegistrar.logger.info(String.format("注册插件 %s(%s)",
					// pluginType.getName(), pluginBeanName));
				} else {
					throw ExceptionUtils
							.throwConfigureException("已存在 " + pluginType.getName() + " Bean :" + pluginBeanName);
				}
			}
			sqlSessionFactoryBeanDef.getPropertyValues().add("plugins", pluginTypeRefs);
		}
		definitionRegistrar.registerBean(info.getSqlSessionFactoryBeanName(), sqlSessionFactoryBeanDef);

		// 注册会话模板
		GenericBeanDefinition sqlSessionTemplateBeanDef = definitionRegistrar
				.createBeanDefinition(SqlSessionTemplate.class, null, null, null);
		sqlSessionTemplateBeanDef.setPrimary(info.isPrimary());
		ref = new RuntimeBeanReference(info.getSqlSessionFactoryBeanName());
		sqlSessionTemplateBeanDef.getConstructorArgumentValues().addGenericArgumentValue(ref);
		definitionRegistrar.registerBean(info.getSqlSessionTemplateBeanName(), sqlSessionTemplateBeanDef);

	}

	/**
	 * 注册Db驱动提供者
	 * 
	 * @param definitionRegistrar
	 *            定义注册
	 * @param mapperScannerRegistrarInfo
	 */
	public static TupleTwo<String, Class<? extends IDbProvider>> registerDbProvider(
			BeanDefinitionRegisterManager definitionRegistrar, DefinitionRegistrarInfo mapperScannerRegistrarInfo) {
		Class<? extends IDbProvider> providerType = ProviderUtils.getOrDefaultDbProviderClass(
				mapperScannerRegistrarInfo.getAutumnDriveType(), mapperScannerRegistrarInfo.getAutumnDriveName());

		String providerBeanName = mapperScannerRegistrarInfo.getProviderBeanName();
		String mapperRegisterBeanName = mapperScannerRegistrarInfo.getMapperRegisterBeanName();

		if (com.autumn.util.StringUtils.isNullOrBlank(providerBeanName)) {
			providerBeanName = definitionRegistrar.generateBeanName(providerType);
		}
		if (com.autumn.util.StringUtils.isNullOrBlank(mapperRegisterBeanName)) {
			mapperRegisterBeanName = definitionRegistrar.generateBeanName(MapperRegister.class);
		}

		GenericBeanDefinition providerBean = definitionRegistrar.createBeanDefinition(providerType, null, null, null);
		providerBean.setPrimary(mapperScannerRegistrarInfo.isPrimary());

		if (!definitionRegistrar.registerBean(providerBeanName, providerBean)) {
			throw ExceptionUtils.throwConfigureException("已存在 DbProvider Bean :" + providerBeanName);
		}

		// definitionRegistrar.logger.info("注册数据提供者 : " + providerType.getName() + "(" +
		// providerBeanName + ")");

		GenericBeanDefinition mapperRegisterBean = definitionRegistrar.createBeanDefinition(MapperRegister.class, null,
				null, null);
		mapperRegisterBean.setPrimary(mapperScannerRegistrarInfo.isPrimary());
		mapperRegisterBean.getConstructorArgumentValues()
				.addGenericArgumentValue(new RuntimeBeanReference(providerBeanName));

		if (!definitionRegistrar.registerBean(mapperRegisterBeanName, mapperRegisterBean)) {
			throw ExceptionUtils.throwConfigureException("已存在 MapperRegister Bean :" + mapperRegisterBeanName);
		}
		return new TupleTwo<>(providerBeanName, providerType);
	}

	private final static String ATTRIBUTE_DATA_SOURCE_ROUTING_TYPE = "dataSourceRoutingType";

	private final static String ATTRIBUTE_DATA_SOURCE_FACTORY_TYPE = "dataSourceFactoryType";

	private final static String ATTRIBUTE_DATA_SOURCE_FACTORY_BEAN_NAME = "dataSourceFactoryBeanName";

	/**
	 * 获取多数据源
	 * 
	 * @param environment
	 * @param importingClassMetadata
	 * @return
	 */
	public static List<DefinitionRegistrarInfo> multipleDataSourceMapperScannerRegistrarInfos(
			Environment environment, AnnotationMetadata importingClassMetadata) {
		int primaryCount = 0;
		AnnotationAttributes annoMultipleAttrs = AnnotationAttributes.fromMap(
				importingClassMetadata.getAnnotationAttributes(EnableAutumnMybatisMultipleDataSource.class.getName()));
		List<DefinitionRegistrarInfo> infos = new ArrayList<>();
		if (annoMultipleAttrs != null) {
			AnnotationAttributes[] annotationClass = annoMultipleAttrs.getAnnotationArray("value");
			if (annotationClass != null) {
				for (AnnotationAttributes annoAttrs : annotationClass) {
					String name = annoAttrs.getString("name");
					if (com.autumn.util.StringUtils.isNullOrBlank(name)) {
						ExceptionUtils.throwConfigureException("多数据源配置属性 name 不能为空。");
					}
					DefinitionRegistrarInfo info = new DefinitionRegistrarInfo();
					info.setName(name);
					info.setPrimary(annoAttrs.getBoolean("primary"));
					info.setDataSourceFactoryType(annoMultipleAttrs.getClass(ATTRIBUTE_DATA_SOURCE_FACTORY_TYPE));
					info.setDataSourceFactoryBeanName(
							annoMultipleAttrs.getString(ATTRIBUTE_DATA_SOURCE_FACTORY_BEAN_NAME));
					setMapperScannerRegistrarInfo(environment, annoAttrs, info);
					if (info.isPrimary()) {
						primaryCount++;
					}
					if (primaryCount > 1) {
						ExceptionUtils.throwConfigureException("多数据源配置 primary = true 只允许存在一项。");
					}
					infos.add(info);
				}
			}
		}
		return infos;
	}

	/**
	 * 获取单数据源
	 * 
	 * @param importingClassMetadata
	 *            导入类元
	 * @return
	 */
	public static DefinitionRegistrarInfo singleDataSourceMapperScannerRegistrarInfos(Environment environment,
			AnnotationMetadata importingClassMetadata) {
		AnnotationAttributes annoAttrs = AnnotationAttributes
				.fromMap(importingClassMetadata.getAnnotationAttributes(EnableAutumnMybatis.class.getName()));
		DefinitionRegistrarInfo info = new DefinitionRegistrarInfo();
		if (annoAttrs == null) {
			return info;
		}
		info.setName(null);
		info.setPrimary(true);
		info.setDataSourceFactoryType(annoAttrs.getClass(ATTRIBUTE_DATA_SOURCE_FACTORY_TYPE));
		info.setDataSourceFactoryBeanName(annoAttrs.getString(ATTRIBUTE_DATA_SOURCE_FACTORY_BEAN_NAME));
		setMapperScannerRegistrarInfo(environment, annoAttrs, info);
		return info;
	}

	/**
	 * 获取动态数据源
	 * 
	 * @param importingClassMetadata
	 *            导入类元
	 * @return
	 */
	public static DefinitionRegistrarInfo dynamicDataSourceMapperScannerRegistrarInfos(Environment environment,
			AnnotationMetadata importingClassMetadata) {
		AnnotationAttributes annoAttrs = AnnotationAttributes.fromMap(
				importingClassMetadata.getAnnotationAttributes(EnableAutumnMybatisDynamicDataSource.class.getName()));
		DefinitionRegistrarInfo info = new DefinitionRegistrarInfo();
		if (annoAttrs == null) {
			return info;
		}
		String name = annoAttrs.getString("name");
		if (com.autumn.util.StringUtils.isNullOrBlank(name)) {
			name = BeanConstant.Dynamic.DEFAULT_DYNAMIC_NAME_PREFIX;
		}
		info.setPrimary(annoAttrs.getBoolean("primary"));
		info.setName(name);
		info.setDataSourceFactoryType(annoAttrs.getClass(ATTRIBUTE_DATA_SOURCE_FACTORY_TYPE));
		info.setDataSourceFactoryBeanName(annoAttrs.getString(ATTRIBUTE_DATA_SOURCE_FACTORY_BEAN_NAME));
		info.setDataSourceRoutingType(annoAttrs.getClass(ATTRIBUTE_DATA_SOURCE_ROUTING_TYPE));
		setMapperScannerRegistrarInfo(environment, annoAttrs, info);
		return info;
	}

	/**
	 * 
	 * @param environment
	 * @param annoAttrs
	 * @param info
	 */
	@SuppressWarnings("unchecked")
	private static <E extends DefinitionRegistrarInfo> void setMapperScannerRegistrarInfo(Environment environment,
			AnnotationAttributes annoAttrs, E info) {
		String[] typeAliasesPackages = annoAttrs.getStringArray("typeAliasesPackages");
		if (typeAliasesPackages != null) {
			info.setTypeAliasesPackage(String.join(";", typeAliasesPackages));
		}
		info.setAutumnDriveName(annoAttrs.getString("autumnDriveName"));
		info.setAutumnDriveType(annoAttrs.getClass("autumnDriveType"));
		info.setPluginTypes((Class<? extends Interceptor>[]) annoAttrs.getClassArray("pluginTypes"));

		info.setMapperInterfacePackages(
				getBasePackages(annoAttrs.getStringArray("value")));

		String configLocation = annoAttrs.getString("configLocation");
		Map<String, Object> rpr = new RelaxedPropertyResolver(environment, MYBATIS_PAHT_DEFAULT).getSubProperties(".");
		if (rpr != null && com.autumn.util.StringUtils.isNullOrBlank(configLocation) && environment != null) {
			Object resObject = rpr.get("configLocation");
			if (resObject != null) {
				configLocation = resObject.toString().replace(CLASSPATH_REPLACE, "");
			}
		}
		info.setConfigLocation(getConfigLocation(configLocation));
		String[] mapperLocations = annoAttrs.getStringArray("mapperLocations");
		if (mapperLocations == null || mapperLocations.length == 0) {
			Object resObject = rpr.get("mapperLocations");
			if (resObject != null) {
				mapperLocations = StringUtils.tokenizeToStringArray(
						resObject.toString().replace(CLASSPATH_REPLACE, "")
								.replace(ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX, ""),
						ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
				for (int i = 0; i < mapperLocations.length; i++) {
					mapperLocations[i] = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + mapperLocations[i];
				}
			}
		}
		info.setMapperLocations(getMapperLocations(mapperLocations));
		info.setDataSourceBeanName(BeanConstant.getDataSourceBeanName(info.getName()));
		info.setTransactionManagerBeanName(BeanConstant.getTransactionManagerBeanName(info.getName()));
		info.setSqlSessionFactoryBeanName(BeanConstant.getSqlSessionFactoryBeanName(info.getName()));
		info.setSqlSessionTemplateBeanName(BeanConstant.getSqlSessionTemplateBeanName(info.getName()));
		info.setProviderBeanName(BeanConstant.getDbProviderBeanName(info.getName()));
		info.setMapperRegisterBeanName(BeanConstant.getMapperRegisterBeanName(info.getName()));
	}

	private static Resource getConfigLocation(String configLocation) {
		if (com.autumn.util.StringUtils.isNullOrBlank(configLocation)) {
			return null;
		}
		return new ClassPathResource(configLocation);
	}

	private static Resource[] getMapperLocations(String[] stringArray) {
		if (stringArray == null || stringArray.length == 0) {
			return null;
		}
		PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
		List<Resource> resources = new ArrayList<Resource>();
		for (String str : stringArray) {
			if (!com.autumn.util.StringUtils.isNullOrBlank(str)) {
				try {
					for (Resource resource : resolver.getResources(str)) {
						resources.add(resource);
					}
				} catch (IOException e) {
					throw ExceptionUtils.throwConfigureException(e.getMessage(), e);
				}
			}
		}
		Resource[] arr = new Resource[resources.size()];
		return resources.toArray(arr);
	}

	/**
	 * 获取包集合
	 * 
	 * @param stringArray
	 * @param addPackages
	 *            追加包
	 * @return
	 */
	private static String[] getBasePackages(String[] stringArray) {
		List<String> basePackages = new ArrayList<String>();
		for (String pkg : stringArray) {
			if (StringUtils.hasText(pkg)) {
				basePackages.add(pkg);
			}
		}		
		return StringUtils.toStringArray(basePackages);
	}

}
